#ifndef LISTENER
#define LISTENER

#include "Socket.hpp"
#include "Channel.hpp"
#include "Connection.hpp"

class Listener : public Connection
{
    static constexpr int defaultPort = 8080;

public:
    Listener(int port = defaultPort)
        : _port(defaultPort),
          _socket_ptr(std::make_unique<SocketModule::TCPSocket>())
    {
        _socket_ptr->BuildTCPSocketfd(_port);
        // 设置关心事件
        SetEvent(EPOLLIN | EPOLLET);

        // SetFd(_socket_ptr->getFD());
        // epoll需要工作在非阻塞状态下，所以必须要设置fd为非阻塞
        setNonBlock(_socket_ptr->getFD());
    }

    void HandleRead() override
    {
        // accept 新连接
        LogModule::LOG(INFO) << "Listener HandleRead()";
        // 一次获取所有连接
        InetAddr client_addr;
        // 循环加非阻塞fd，处理accept的错误和正确情况
        while (true)
        {
            int connfd = _socket_ptr->AcceptSocket(&client_addr);

            if (connfd == ACCEPT_ERR)
                break;
            else if (connfd == ACCEPT_CONTINUE)
                continue;
            else if (connfd == ACCEPT_DONE)
                break;
            // 获得了一个真正可用的fd
            else
            {
                LogModule::LOG(INFO) << "get a new fd" << connfd;
                // 普通fd使用Channel封装，创建一个新的连接
                std::shared_ptr<Connection> new_conn = std::make_shared<Channel>(connfd, client_addr);
                // 设置关心事件以及设置ET模式
                LogModule::LOG(DEBUG) << "进入到设置事件";
                new_conn->SetEvent(EPOLLIN | EPOLLET);
                LogModule::LOG(DEBUG) << "添加新连接，进入到回调函数处理";

                // 设置回调函数处理
                new_conn->SetHandleRegeister(_handler);
                LogModule::LOG(DEBUG) << "添加新连接到哈希表";

                // 添加连接
                GetOwner()->AddConnection(new_conn);
            }
        }
    };
    void HandleWrite() override
    {
        LogModule::LOG(INFO) << "Listener HandleWrite()";
    }
    void HandleExcepter() override {}

    // 实现纯虚函数
    int GetSockFd() const override
    {
        return _socket_ptr->getFD();
    }

    ~Listener() {}

private:
    // 监听端口
    int _port;

    std::unique_ptr<SocketModule::Socket> _socket_ptr;
};

#endif
